package com.hotel.hotelsystem.controller;



import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;

import com.common.status.ResultMsg;
import com.common.status.StatusCode;
import com.common.utils.LocalDateTimeToTimeStamp;
import com.common.utils.ResultUtils;
import com.common.utils.ResultVo;
import com.hotel.config.websocket.WebSocketProcess;
import com.hotel.customersystem.pojo.CustomerUserCoupon;
import com.hotel.customersystem.service.CustomerUserCouponService;
import com.hotel.hotelsystem.pojo.HotelImageList;
import com.hotel.hotelsystem.pojo.HotelInfo;
import com.hotel.hotelsystem.pojo.HotelList;
import com.hotel.hotelsystem.pojo.vo.CouponSeckilVo;
import com.hotel.hotelsystem.pojo.vo.CouponVo;
import com.hotel.hotelsystem.service.HotelImageListService;
import com.hotel.hotelsystem.service.HotelInfoService;
import com.hotel.hotelsystem.service.HotelListService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchHit;
import org.springframework.data.elasticsearch.core.SearchHits;
import org.springframework.data.elasticsearch.core.query.NativeSearchQuery;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import static com.hotel.config.rabbitmq.config.DelayConfig.SECKIL_COUPON_EXCHANGE;
import static com.hotel.config.rabbitmq.config.DelayConfig.SECKIL_COUPON_ROUTER_KEY;


/**
 * (HotelList)表控制层
 *
 * @author makejava
 * @since 2022-09-30 18:23:16
 */
@Slf4j
@Api(value = "HotelListController",tags = {"酒店业务模块"})
@RestController
@RequestMapping("hotel")
public class HotelListController {
    /**
     * 服务对象
     */
    @Resource
    private HotelInfoService hotelInfoService; // 酒店信息
    @Resource
    private HotelListService hotelListService; // 酒店列表
    @Resource
    private HotelImageListService hotelImageListService; // 酒店图片
    @Resource
    private RabbitTemplate rabbitTemplate; // 消息队列组件库
    @Resource
    private WebSocketProcess webSocketProcess; // 消息推送
    @Resource
    private ElasticsearchRestTemplate elasticsearchRestTemplate; // 热搜索组件
    @Resource
    private CustomerUserCouponService customerUserCouponService;

    @ApiOperation(value = "所有详情信息")
    @GetMapping("/getIHotelInfoList")
    public ResultVo<List<HotelInfo>> getIHotelInfoList() {
        List<HotelInfo> list = hotelInfoService.list();
        if (list.size() != 0) return ResultUtils.success(ResultMsg.SUCCESS_MSG, StatusCode.SUCCESS_CODE,list);
        else return ResultUtils.error(ResultMsg.DATA_NULL, StatusCode.SYSTEM_ERROR_CODE,null);
    }

    @ApiOperation(value = "酒店列表")
    @GetMapping("/getIHotelList")
    public ResultVo<List<HotelList>> getIHotelList() {
        List<HotelList> list = hotelListService.list();
        if (list.size() != 0) return ResultUtils.success(ResultMsg.SUCCESS_MSG, StatusCode.SUCCESS_CODE,list);
        else return ResultUtils.error(ResultMsg.DATA_NULL, StatusCode.SYSTEM_ERROR_CODE,null);
    }

    @ApiOperation(value = "所有图片列表")
    @GetMapping("/getImageList")
    public ResultVo<List<HotelImageList>> getImageList() {
        List<HotelImageList> list = hotelImageListService.list();
        if (list.size() != 0) return ResultUtils.success(ResultMsg.SUCCESS_MSG, StatusCode.SUCCESS_CODE,list);
        else return ResultUtils.error(ResultMsg.DATA_NULL, StatusCode.SYSTEM_ERROR_CODE,null);
    }

    @ApiOperation(value = "添加酒店")
    @PostMapping("/addHotelList")
    public ResultVo<HotelList> addHotelList(@RequestBody HotelList hotelList ){
        boolean flag=hotelListService.save(hotelList);
        if(flag){
            return  ResultUtils.success(ResultMsg.SUCCESS_MSG,StatusCode.SUCCESS_CODE,flag);

        }else{
            return  ResultUtils.error(ResultMsg.ERROR_MSG,StatusCode.SYSTEM_ERROR_CODE,flag);
        }

    }
    @ApiOperation(value = "根据ID删除酒店")
    @DeleteMapping("/delete")
    public ResultVo<Boolean> deleteHotelList(@RequestParam Integer hotelSelectId) {
        boolean flag=hotelListService.deleteBySelectId(hotelSelectId);
        if(flag) {
            return ResultUtils.success(ResultMsg.SUCCESS_MSG,StatusCode.SUCCESS_CODE,flag);

        }else{
            return ResultUtils.error(ResultMsg.ERROR_MSG,StatusCode.SYSTEM_ERROR_CODE,flag);
        }
    }

    @ApiOperation(value = "修改酒店信息")
    @PutMapping("/updateHotelList")
    public ResultVo<Boolean> updateHotelList(@RequestBody HotelList hotelList){
        boolean flag=hotelListService.update(hotelList,null);
        if(flag) return ResultUtils.success(ResultMsg.SUCCESS_MSG,StatusCode.SUCCESS_CODE,flag);
        else return ResultUtils.error(ResultMsg.ERROR_MSG,StatusCode.SYSTEM_ERROR_CODE,flag);
    }

    @ApiOperation(value = "查询酒店信息")
    @GetMapping("/searchHotelList")
    public ResultVo<List<HotelList>> searchHotelList(){
        List<HotelList> lists=hotelListService.list();
        if(lists.size() != 0) return ResultUtils.success(ResultMsg.SUCCESS_MSG,StatusCode.SUCCESS_CODE,lists);
        else return ResultUtils.error(ResultMsg.ERROR_MSG,StatusCode.SYSTEM_ERROR_CODE,null);
    }

    @ApiOperation(value = "多条件查询酒店信息")
    @GetMapping("/selectByCondition")
    public ResultVo<List<HotelList>> selectByCondition(@RequestParam(value = "hotelName")String hotelName,@RequestParam(value = "starRanting") Integer starRanting){
        LambdaQueryWrapper<HotelList> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.like(HotelList::getHotelName,hotelName).eq(HotelList::getStarRanting,String.valueOf(starRanting));
        List<HotelList> list = hotelListService.list(queryWrapper);
        if(list.size() != 0) return ResultUtils.success(ResultMsg.SUCCESS_MSG,StatusCode.SUCCESS_CODE,list);
        else return ResultUtils.error(ResultMsg.ERROR_MSG,StatusCode.SYSTEM_ERROR_CODE,null);
    }

    @ApiOperation(value = "分页查询酒店的信息")
    @GetMapping("/getByPage")
    public ResultVo<IPage<HotelList>> getByPage(@RequestParam Integer currentPage, @RequestParam Integer pageSize){
        IPage<HotelList> page=hotelListService.getByPage(currentPage,pageSize);
        return ResultUtils.success(ResultMsg.SUCCESS_MSG,StatusCode.SUCCESS_CODE,page);
    }


    @ApiOperation(value = "首页高亮热搜索")
    @GetMapping("/elasticSearchByKeyWord")
    public ResultVo<List<HotelList>> elasticSearchByKeyWord(@RequestParam("keyWord") String keyWord) {
        log.info("关键字:",keyWord);
        // 创建query对象
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery()
                .should(QueryBuilders.matchQuery("hotelName",keyWord)) // 酒店名字
                .should(QueryBuilders.matchQuery("starRanting",keyWord)); // 星级
        // 构建高亮查询
        NativeSearchQuery searchQuery = new NativeSearchQueryBuilder()
                .withQuery(boolQueryBuilder)
                .withHighlightFields(new HighlightBuilder.Field("hotelName"))
                .withHighlightFields(new HighlightBuilder.Field("starRanting"))
                .withHighlightBuilder(new HighlightBuilder()
                        .preTags("<span style='color:yellow'>")
                        .postTags("</span>"))
                .build();
        // 查询
        SearchHits<HotelList> search = elasticsearchRestTemplate.search(searchQuery,HotelList.class);
        // 得到查询返回的内容
        List<SearchHit<HotelList>> searchHits = search.getSearchHits();
        log.info("结果:",searchHits);
        // 设置返回结果的集合
        List<HotelList> hotelLists = new ArrayList<>();
        for (SearchHit<HotelList> searchHit : searchHits) {
            // 高亮内容
            Map<String,List<String>> highlightFields = searchHit.getHighlightFields();
            // 将高亮内容填充到content中
            String hotelName = highlightFields.get("hotelName") == null?searchHit.getContent().getHotelName():highlightFields.get("hotelName").get(0);
            Integer starRanting = highlightFields.get("starRanting") == null?searchHit.getContent().getStarRanting():Integer.parseInt(highlightFields.get("starRanting").get(0));
            searchHit.getContent().setHotelName(hotelName);
            searchHit.getContent().setStarRanting(starRanting);
            hotelLists.add(searchHit.getContent());
        }
        return ResultUtils.success(ResultMsg.SUCCESS_MSG,StatusCode.SUCCESS_CODE,hotelLists);
    }

    @ApiOperation(value = "延时插件解决优惠券秒杀问题")
    @PostMapping("/delaySeckilCoupon")
    public String delaySeckilCoupon(@RequestBody Map map, @RequestParam(value = "userAdmin") String userAdmin) {
        System.out.println(map);
        CouponVo couponVo = JSON.parseObject(JSON.toJSONString(map), CouponVo.class);
        couponVo.setUserAdmin(userAdmin);
        System.out.println(couponVo);
        rabbitTemplate.convertAndSend(SECKIL_COUPON_EXCHANGE,SECKIL_COUPON_ROUTER_KEY,couponVo);
        return "秒杀成功";
    }

    @ApiOperation(value = "按ID查询酒店")
    @GetMapping("/getById")
    public ResultVo<HotelList> getById(@RequestParam("id") Integer hotelId) {
        QueryWrapper<HotelList> qw = new QueryWrapper<>();
        qw.eq("hotel_id", hotelId);
        HotelList hotelList = hotelListService.getOne(qw);
        return ResultUtils.success(ResultMsg.SUCCESS_MSG, StatusCode.SUCCESS_CODE, hotelList);
    }

    @ApiOperation(value = "判断用户是否已拥有该优惠券")
    @GetMapping("/isOwnerCoupon")
    public ResultVo<Boolean> isOwnerCoupon(@RequestParam(value = "userAdmin") String userAdmin,@RequestParam(value = "couponNo") String couponNo) {
        LambdaQueryWrapper<CustomerUserCoupon> ldq = new LambdaQueryWrapper<>();
        ldq.eq(CustomerUserCoupon::getCouponNo,couponNo).eq(CustomerUserCoupon::getStandby01,userAdmin);
        CustomerUserCoupon one = customerUserCouponService.getOne(ldq);
//     QueryWrapper wrapper = new QueryWrapper();
//     wrapper.eq("coupon_no",couponNo);
//     wrapper.eq("standby01",userAdmin);
//        CustomerUserCoupon one = customerUserCouponService.getOne(wrapper);
        if ( one != null) return ResultUtils.success(ResultMsg.SUCCESS_MSG,StatusCode.SUCCESS_CODE,true);
        else return ResultUtils.error(ResultMsg.ERROR_MSG,StatusCode.SYSTEM_ERROR_CODE,false);
    }
}

